Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: change event allows getting a list of the changes made #1585

Open
wants to merge 5 commits into
base: feat/blocknote-transactions
Choose a base branch
from

Conversation

nperez0111
Copy link
Contributor

@nperez0111 nperez0111 commented Apr 4, 2025

This implements a getChanges API which will derive the changes made within a transaction as a list of: inserts, updates and deletions of blocknote blocks

To test this you can update an example like so:

diff --git i/examples/01-basic/01-minimal/App.tsx w/examples/01-basic/01-minimal/App.tsx
index a3b92bafd..d5c43ac2b 100644
--- i/examples/01-basic/01-minimal/App.tsx
+++ w/examples/01-basic/01-minimal/App.tsx
@@ -8,5 +8,12 @@ export default function App() {
   const editor = useCreateBlockNote();
 
   // Renders the editor instance using a React component.
-  return <BlockNoteView editor={editor} />;
+  return (
+    <BlockNoteView
+      editor={editor}
+      onChange={(t, ctx) => {
+        console.log("changes", ctx.getChanges());
+      }}
+    />
+  );
 }

Things left:

  • add tests

Resolves #1541 #482 #1566

Copy link

vercel bot commented Apr 4, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
blocknote ✅ Ready (Inspect) Visit Preview Apr 8, 2025 11:50am
blocknote-website ✅ Ready (Inspect) Visit Preview Apr 8, 2025 11:50am

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

Copy link

pkg-pr-new bot commented Apr 7, 2025

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/ariakit@1585

@blocknote/code-block

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/code-block@1585

@blocknote/core

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@1585

@blocknote/mantine

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/mantine@1585

@blocknote/react

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@1585

@blocknote/server-util

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/server-util@1585

@blocknote/shadcn

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/shadcn@1585

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-docx-exporter@1585

@blocknote/xl-multi-column

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-multi-column@1585

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-odt-exporter@1585

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-pdf-exporter@1585

commit: 4f5325f

Copy link
Collaborator

@YousefED YousefED left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is so awesome, and implementation actually cleaner / clearer than expected! really cool

} else if (transaction.getMeta("uiEvent") === "drop") {
source = { type: "drop" };
} else if (transaction.getMeta("history$")) {
source = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this work for collaboration as well (yjs history)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works only for the history plugin. But, I think y-prosemirror tells us if an undo happened (unsure if locally or remote or both), so maybe I can do it for that too

const changes: BlocksChanged<BSchema, ISchema, SSchema> = [];
// TODO when we upgrade to Tiptap v3, we can get the appendedTransactions which would give us things like the actual inserted Block IDs.
// since they are appended to the transaction via the unique-id plugin
const combinedTransaction = combineTransactionSteps(transaction.before, [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't completely understand this. How do we get the block ids now then, if we don't yet support the uniqueid transactions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tiptap V2 gives the root tr that was applied which does not include any appended transactions (since it is only the root tr).
Tiptap V3 gives both root tr & any appended transaction in that callback which means you can see the appended transactions & re-combine them to get the "actual" changed ranges.

Technically, the editor state is up to date by the time we are reading this, but we can't know what transactions have been appended so our transaction ranges can be incorrect.

The reason that we are getting ids out of this right now is that nodeToBlock will generate an ID if it does not find one. But, those IDs are not the same ID that actually would have been persisted into the document.

let originalDispatch: typeof editor.dispatch;

beforeEach(() => {
transaction = undefined as unknown as Transaction;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not easier to test the onchange event directly instead of patching like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely easier, but the test is not for the change event, but to see if a transaction can give us the changes. I'd want it isolated


const getEditor = setupTestEnv();

describe("Test getBlocksChangedByTransaction", () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add test-cases for child blocks (add / update / delete child blocks). We can debate whether this should trigger a change on the parent or not, but at least it should be tested / documented imo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed should be in the tests

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants